home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / Kubuntu 8.10 / kubuntu-8.10-desktop-i386.iso / casper / filesystem.squashfs / usr / lib / python2.5 / platform.pyc (.txt) < prev    next >
Python Compiled Bytecode  |  2008-10-29  |  30KB  |  1,090 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.5)
  3.  
  4. ''' This module tries to retrieve as much platform-identifying data as
  5.     possible. It makes this information available via function APIs.
  6.  
  7.     If called from the command line, it prints the platform
  8.     information concatenated as single string to stdout. The output
  9.     format is useable as part of a filename.
  10.  
  11. '''
  12. __copyright__ = '\n    Copyright (c) 1999-2000, Marc-Andre Lemburg; mailto:mal@lemburg.com\n    Copyright (c) 2000-2003, eGenix.com Software GmbH; mailto:info@egenix.com\n\n    Permission to use, copy, modify, and distribute this software and its\n    documentation for any purpose and without fee or royalty is hereby granted,\n    provided that the above copyright notice appear in all copies and that\n    both that copyright notice and this permission notice appear in\n    supporting documentation or portions thereof, including modifications,\n    that you make.\n\n    EGENIX.COM SOFTWARE GMBH DISCLAIMS ALL WARRANTIES WITH REGARD TO\n    THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND\n    FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,\n    INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING\n    FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,\n    NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION\n    WITH THE USE OR PERFORMANCE OF THIS SOFTWARE !\n\n'
  13. __version__ = '1.0.4'
  14. import sys
  15. import string
  16. import os
  17. import re
  18. _libc_search = re.compile('(__libc_init)|(GLIBC_([0-9.]+))|(libc(_\\w+)?\\.so(?:\\.(\\d[0-9.]*))?)')
  19.  
  20. def libc_ver(executable = sys.executable, lib = '', version = '', chunksize = 2048):
  21.     ''' Tries to determine the libc version that the file executable
  22.         (which defaults to the Python interpreter) is linked against.
  23.  
  24.         Returns a tuple of strings (lib,version) which default to the
  25.         given parameters in case the lookup fails.
  26.  
  27.         Note that the function has intimate knowledge of how different
  28.         libc versions add symbols to the executable and thus is probably
  29.         only useable for executables compiled using gcc.
  30.  
  31.         The file is read and scanned in chunks of chunksize bytes.
  32.  
  33.     '''
  34.     f = open(executable, 'rb')
  35.     binary = f.read(chunksize)
  36.     pos = 0
  37.     while None:
  38.         m = _libc_search.search(binary, pos)
  39.         if not m:
  40.             binary = f.read(chunksize)
  41.             if not binary:
  42.                 break
  43.             
  44.             pos = 0
  45.             continue
  46.         
  47.         (libcinit, glibc, glibcversion, so, threads, soversion) = m.groups()
  48.         if libcinit and not lib:
  49.             lib = 'libc'
  50.         elif glibc:
  51.             if lib != 'glibc':
  52.                 lib = 'glibc'
  53.                 version = glibcversion
  54.             elif glibcversion > version:
  55.                 version = glibcversion
  56.             
  57.         elif so:
  58.             if lib != 'glibc':
  59.                 lib = 'libc'
  60.                 if soversion > version:
  61.                     version = soversion
  62.                 
  63.                 if threads and version[-len(threads):] != threads:
  64.                     version = version + threads
  65.                 
  66.             
  67.         
  68.         pos = m.end()
  69.         continue
  70.         return (lib, version)
  71.  
  72.  
  73. def _dist_try_harder(distname, version, id):
  74.     ''' Tries some special tricks to get the distribution
  75.         information in case the default method fails.
  76.  
  77.         Currently supports older SuSE Linux, Caldera OpenLinux and
  78.         Slackware Linux distributions.
  79.  
  80.     '''
  81.     if os.path.exists('/var/adm/inst-log/info'):
  82.         info = open('/var/adm/inst-log/info').readlines()
  83.         distname = 'SuSE'
  84.         for line in info:
  85.             tv = string.split(line)
  86.             if len(tv) == 2:
  87.                 (tag, value) = tv
  88.             
  89.             if tag == 'MIN_DIST_VERSION':
  90.                 version = string.strip(value)
  91.                 continue
  92.             len(tv) == 2
  93.             if tag == 'DIST_IDENT':
  94.                 values = string.split(value, '-')
  95.                 id = values[2]
  96.                 continue
  97.         
  98.         return (distname, version, id)
  99.     
  100.     if os.path.exists('/etc/.installed'):
  101.         info = open('/etc/.installed').readlines()
  102.         for line in info:
  103.             pkg = string.split(line, '-')
  104.             if len(pkg) >= 2 and pkg[0] == 'OpenLinux':
  105.                 return ('OpenLinux', pkg[1], id)
  106.                 continue
  107.         
  108.     
  109.     if os.path.isdir('/usr/lib/setup'):
  110.         verfiles = os.listdir('/usr/lib/setup')
  111.         for n in range(len(verfiles) - 1, -1, -1):
  112.             if verfiles[n][:14] != 'slack-version-':
  113.                 del verfiles[n]
  114.                 continue
  115.         
  116.         if verfiles:
  117.             verfiles.sort()
  118.             distname = 'slackware'
  119.             version = verfiles[-1][14:]
  120.             return (distname, version, id)
  121.         
  122.     
  123.     return (distname, version, id)
  124.  
  125. _release_filename = re.compile('(\\w+)[-_](release|version)')
  126. _release_version = re.compile('([\\d.]+)[^(]*(?:\\((.+)\\))?')
  127.  
  128. def dist(distname = '', version = '', id = '', supported_dists = ('SuSE', 'debian', 'fedora', 'redhat', 'mandrake')):
  129.     ''' Tries to determine the name of the Linux OS distribution name.
  130.  
  131.         The function first looks for a distribution release file in
  132.         /etc and then reverts to _dist_try_harder() in case no
  133.         suitable files are found.
  134.  
  135.         Returns a tuple (distname,version,id) which default to the
  136.         args given as parameters.
  137.  
  138.     '''
  139.     
  140.     try:
  141.         etc = os.listdir('/etc')
  142.     except os.error:
  143.         return (distname, version, id)
  144.  
  145.     for file in etc:
  146.         m = _release_filename.match(file)
  147.         if m:
  148.             (_distname, dummy) = m.groups()
  149.             if _distname in supported_dists:
  150.                 distname = _distname
  151.                 break
  152.             
  153.         _distname in supported_dists
  154.     else:
  155.         return _dist_try_harder(distname, version, id)
  156.     f = open('/etc/' + file, 'r')
  157.     firstline = f.readline()
  158.     f.close()
  159.     m = _release_version.search(firstline)
  160.     if m:
  161.         (_version, _id) = m.groups()
  162.         if _version:
  163.             version = _version
  164.         
  165.         if _id:
  166.             id = _id
  167.         
  168.     else:
  169.         l = string.split(string.strip(firstline))
  170.         if l:
  171.             version = l[0]
  172.             if len(l) > 1:
  173.                 id = l[1]
  174.             
  175.         
  176.     return (distname, version, id)
  177.  
  178.  
  179. class _popen:
  180.     """ Fairly portable (alternative) popen implementation.
  181.  
  182.         This is mostly needed in case os.popen() is not available, or
  183.         doesn't work as advertised, e.g. in Win9X GUI programs like
  184.         PythonWin or IDLE.
  185.  
  186.         Writing to the pipe is currently not supported.
  187.  
  188.     """
  189.     tmpfile = ''
  190.     pipe = None
  191.     bufsize = None
  192.     mode = 'r'
  193.     
  194.     def __init__(self, cmd, mode = 'r', bufsize = None):
  195.         if mode != 'r':
  196.             raise ValueError, 'popen()-emulation only supports read mode'
  197.         
  198.         import tempfile as tempfile
  199.         self.tmpfile = tmpfile = tempfile.mktemp()
  200.         os.system(cmd + ' > %s' % tmpfile)
  201.         self.pipe = open(tmpfile, 'rb')
  202.         self.bufsize = bufsize
  203.         self.mode = mode
  204.  
  205.     
  206.     def read(self):
  207.         return self.pipe.read()
  208.  
  209.     
  210.     def readlines(self):
  211.         if self.bufsize is not None:
  212.             return self.pipe.readlines()
  213.         
  214.  
  215.     
  216.     def close(self, remove = os.unlink, error = os.error):
  217.         if self.pipe:
  218.             rc = self.pipe.close()
  219.         else:
  220.             rc = 255
  221.         if self.tmpfile:
  222.             
  223.             try:
  224.                 remove(self.tmpfile)
  225.             except error:
  226.                 pass
  227.             except:
  228.                 None<EXCEPTION MATCH>error
  229.             
  230.  
  231.         None<EXCEPTION MATCH>error
  232.         return rc
  233.  
  234.     __del__ = close
  235.  
  236.  
  237. def popen(cmd, mode = 'r', bufsize = None):
  238.     ''' Portable popen() interface.
  239.     '''
  240.     popen = None
  241.     if os.environ.get('OS', '') == 'Windows_NT':
  242.         
  243.         try:
  244.             import win32pipe as win32pipe
  245.         except ImportError:
  246.             pass
  247.  
  248.         popen = win32pipe.popen
  249.     
  250.     if popen is None:
  251.         if hasattr(os, 'popen'):
  252.             popen = os.popen
  253.             if sys.platform == 'win32':
  254.                 
  255.                 try:
  256.                     popen('')
  257.                 except os.error:
  258.                     popen = _popen
  259.                 except:
  260.                     None<EXCEPTION MATCH>os.error
  261.                 
  262.  
  263.             None<EXCEPTION MATCH>os.error
  264.         else:
  265.             popen = _popen
  266.     
  267.     if bufsize is None:
  268.         return popen(cmd, mode)
  269.     else:
  270.         return popen(cmd, mode, bufsize)
  271.  
  272.  
  273. def _norm_version(version, build = ''):
  274.     ''' Normalize the version and build strings and return a single
  275.         version string using the format major.minor.build (or patchlevel).
  276.     '''
  277.     l = string.split(version, '.')
  278.     if build:
  279.         l.append(build)
  280.     
  281.     
  282.     try:
  283.         ints = map(int, l)
  284.     except ValueError:
  285.         strings = l
  286.  
  287.     strings = map(str, ints)
  288.     version = string.join(strings[:3], '.')
  289.     return version
  290.  
  291. _ver_output = re.compile('(?:([\\w ]+) ([\\w.]+) .*Version ([\\d.]+))')
  292.  
  293. def _syscmd_ver(system = '', release = '', version = '', supported_platforms = ('win32', 'win16', 'dos', 'os2')):
  294.     ''' Tries to figure out the OS version used and returns
  295.         a tuple (system,release,version).
  296.  
  297.         It uses the "ver" shell command for this which is known
  298.         to exists on Windows, DOS and OS/2. XXX Others too ?
  299.  
  300.         In case this fails, the given parameters are used as
  301.         defaults.
  302.  
  303.     '''
  304.     if sys.platform not in supported_platforms:
  305.         return (system, release, version)
  306.     
  307.     for cmd in ('ver', 'command /c ver', 'cmd /c ver'):
  308.         
  309.         try:
  310.             pipe = popen(cmd)
  311.             info = pipe.read()
  312.             if pipe.close():
  313.                 raise os.error, 'command failed'
  314.         except os.error:
  315.             why = None
  316.             continue
  317.             continue
  318.             except IOError:
  319.                 why = None
  320.                 continue
  321.                 continue
  322.             else:
  323.                 break
  324.         return (system, release, version)
  325.         info = string.strip(info)
  326.         m = _ver_output.match(info)
  327.         if m:
  328.             (system, release, version) = m.groups()
  329.             if release[-1] == '.':
  330.                 release = release[:-1]
  331.             
  332.             if version[-1] == '.':
  333.                 version = version[:-1]
  334.             
  335.             version = _norm_version(version)
  336.         
  337.  
  338.     return (system, release, version)
  339.  
  340.  
  341. def _win32_getvalue(key, name, default = ''):
  342.     ''' Read a value for name from the registry key.
  343.  
  344.         In case this fails, default is returned.
  345.  
  346.     '''
  347.     RegQueryValueEx = RegQueryValueEx
  348.     import win32api
  349.     
  350.     try:
  351.         return RegQueryValueEx(key, name)
  352.     except:
  353.         return default
  354.  
  355.  
  356.  
  357. def win32_ver(release = '', version = '', csd = '', ptype = ''):
  358.     """ Get additional version information from the Windows Registry
  359.         and return a tuple (version,csd,ptype) referring to version
  360.         number, CSD level and OS type (multi/single
  361.         processor).
  362.  
  363.         As a hint: ptype returns 'Uniprocessor Free' on single
  364.         processor NT machines and 'Multiprocessor Free' on multi
  365.         processor machines. The 'Free' refers to the OS version being
  366.         free of debugging code. It could also state 'Checked' which
  367.         means the OS version uses debugging code, i.e. code that
  368.         checks arguments, ranges, etc. (Thomas Heller).
  369.  
  370.         Note: this function only works if Mark Hammond's win32
  371.         package is installed and obviously only runs on Win32
  372.         compatible platforms.
  373.  
  374.     """
  375.     
  376.     try:
  377.         import win32api
  378.     except ImportError:
  379.         return (release, version, csd, ptype)
  380.  
  381.     RegQueryValueEx = RegQueryValueEx
  382.     RegOpenKeyEx = RegOpenKeyEx
  383.     RegCloseKey = RegCloseKey
  384.     GetVersionEx = GetVersionEx
  385.     import win32api
  386.     HKEY_LOCAL_MACHINE = HKEY_LOCAL_MACHINE
  387.     VER_PLATFORM_WIN32_NT = VER_PLATFORM_WIN32_NT
  388.     VER_PLATFORM_WIN32_WINDOWS = VER_PLATFORM_WIN32_WINDOWS
  389.     import win32con
  390.     (maj, min, buildno, plat, csd) = GetVersionEx()
  391.     version = '%i.%i.%i' % (maj, min, buildno & 65535)
  392.     if csd[:13] == 'Service Pack ':
  393.         csd = 'SP' + csd[13:]
  394.     
  395.     if plat == VER_PLATFORM_WIN32_WINDOWS:
  396.         regkey = 'SOFTWARE\\Microsoft\\Windows\\CurrentVersion'
  397.         if maj == 4:
  398.             if min == 0:
  399.                 release = '95'
  400.             elif min == 10:
  401.                 release = '98'
  402.             elif min == 90:
  403.                 release = 'Me'
  404.             else:
  405.                 release = 'postMe'
  406.         elif maj == 5:
  407.             release = '2000'
  408.         
  409.     elif plat == VER_PLATFORM_WIN32_NT:
  410.         regkey = 'SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion'
  411.         if maj <= 4:
  412.             release = 'NT'
  413.         elif maj == 5:
  414.             if min == 0:
  415.                 release = '2000'
  416.             elif min == 1:
  417.                 release = 'XP'
  418.             elif min == 2:
  419.                 release = '2003Server'
  420.             else:
  421.                 release = 'post2003'
  422.         
  423.     elif not release:
  424.         release = '%i.%i' % (maj, min)
  425.     
  426.     return (release, version, csd, ptype)
  427.     
  428.     try:
  429.         keyCurVer = RegOpenKeyEx(HKEY_LOCAL_MACHINE, regkey)
  430.         RegQueryValueEx(keyCurVer, 'SystemRoot')
  431.     except:
  432.         return (release, version, csd, ptype)
  433.  
  434.     build = _win32_getvalue(keyCurVer, 'CurrentBuildNumber', ('', 1))[0]
  435.     ptype = _win32_getvalue(keyCurVer, 'CurrentType', (ptype, 1))[0]
  436.     version = _norm_version(version, build)
  437.     RegCloseKey(keyCurVer)
  438.     return (release, version, csd, ptype)
  439.  
  440.  
  441. def _mac_ver_lookup(selectors, default = None):
  442.     gestalt = gestalt
  443.     import gestalt
  444.     import MacOS as MacOS
  445.     l = []
  446.     append = l.append
  447.     for selector in selectors:
  448.         
  449.         try:
  450.             append(gestalt(selector))
  451.         continue
  452.         except (RuntimeError, MacOS.Error):
  453.             append(default)
  454.             continue
  455.         
  456.  
  457.     
  458.     return l
  459.  
  460.  
  461. def _bcd2str(bcd):
  462.     return hex(bcd)[2:]
  463.  
  464.  
  465. def mac_ver(release = '', versioninfo = ('', '', ''), machine = ''):
  466.     """ Get MacOS version information and return it as tuple (release,
  467.         versioninfo, machine) with versioninfo being a tuple (version,
  468.         dev_stage, non_release_version).
  469.  
  470.         Entries which cannot be determined are set to the paramter values
  471.         which default to ''. All tuple entries are strings.
  472.  
  473.         Thanks to Mark R. Levinson for mailing documentation links and
  474.         code examples for this function. Documentation for the
  475.         gestalt() API is available online at:
  476.  
  477.            http://www.rgaros.nl/gestalt/
  478.  
  479.     """
  480.     
  481.     try:
  482.         import gestalt
  483.         import MacOS
  484.     except ImportError:
  485.         return (release, versioninfo, machine)
  486.  
  487.     (sysv, sysu, sysa) = _mac_ver_lookup(('sysv', 'sysu', 'sysa'))
  488.     if sysv:
  489.         major = (sysv & 65280) >> 8
  490.         minor = (sysv & 240) >> 4
  491.         patch = sysv & 15
  492.         if (major, minor) >= (10, 4):
  493.             (major, minor, patch) = _mac_ver_lookup(('sys1', 'sys2', 'sys3'))
  494.             release = '%i.%i.%i' % (major, minor, patch)
  495.         else:
  496.             release = '%s.%i.%i' % (_bcd2str(major), minor, patch)
  497.     
  498.     if sysu:
  499.         major = int((sysu & 0xFF000000L) >> 24)
  500.         minor = (sysu & 15728640) >> 20
  501.         bugfix = (sysu & 983040) >> 16
  502.         stage = (sysu & 65280) >> 8
  503.         nonrel = sysu & 255
  504.         version = '%s.%i.%i' % (_bcd2str(major), minor, bugfix)
  505.         nonrel = _bcd2str(nonrel)
  506.         stage = {
  507.             32: 'development',
  508.             64: 'alpha',
  509.             96: 'beta',
  510.             128: 'final' }.get(stage, '')
  511.         versioninfo = (version, stage, nonrel)
  512.     
  513.     if sysa:
  514.         machine = {
  515.             1: '68k',
  516.             2: 'PowerPC',
  517.             10: 'i386' }.get(sysa, '')
  518.     
  519.     return (release, versioninfo, machine)
  520.  
  521.  
  522. def _java_getprop(name, default):
  523.     System = System
  524.     import java.lang
  525.     
  526.     try:
  527.         return System.getProperty(name)
  528.     except:
  529.         return default
  530.  
  531.  
  532.  
  533. def java_ver(release = '', vendor = '', vminfo = ('', '', ''), osinfo = ('', '', '')):
  534.     """ Version interface for Jython.
  535.  
  536.         Returns a tuple (release,vendor,vminfo,osinfo) with vminfo being
  537.         a tuple (vm_name,vm_release,vm_vendor) and osinfo being a
  538.         tuple (os_name,os_version,os_arch).
  539.  
  540.         Values which cannot be determined are set to the defaults
  541.         given as parameters (which all default to '').
  542.  
  543.     """
  544.     
  545.     try:
  546.         import java.lang as java
  547.     except ImportError:
  548.         return (release, vendor, vminfo, osinfo)
  549.  
  550.     vendor = _java_getprop('java.vendor', vendor)
  551.     release = _java_getprop('java.version', release)
  552.     (vm_name, vm_release, vm_vendor) = vminfo
  553.     vm_name = _java_getprop('java.vm.name', vm_name)
  554.     vm_vendor = _java_getprop('java.vm.vendor', vm_vendor)
  555.     vm_release = _java_getprop('java.vm.version', vm_release)
  556.     vminfo = (vm_name, vm_release, vm_vendor)
  557.     (os_name, os_version, os_arch) = osinfo
  558.     os_arch = _java_getprop('java.os.arch', os_arch)
  559.     os_name = _java_getprop('java.os.name', os_name)
  560.     os_version = _java_getprop('java.os.version', os_version)
  561.     osinfo = (os_name, os_version, os_arch)
  562.     return (release, vendor, vminfo, osinfo)
  563.  
  564.  
  565. def system_alias(system, release, version):
  566.     ''' Returns (system,release,version) aliased to common
  567.         marketing names used for some systems.
  568.  
  569.         It also does some reordering of the information in some cases
  570.         where it would otherwise cause confusion.
  571.  
  572.     '''
  573.     if system == 'Rhapsody':
  574.         return ('MacOS X Server', system + release, version)
  575.     elif system == 'SunOS':
  576.         if release < '5':
  577.             return (system, release, version)
  578.         
  579.         l = string.split(release, '.')
  580.         if l:
  581.             
  582.             try:
  583.                 major = int(l[0])
  584.             except ValueError:
  585.                 pass
  586.  
  587.             major = major - 3
  588.             l[0] = str(major)
  589.             release = string.join(l, '.')
  590.         
  591.         if release < '6':
  592.             system = 'Solaris'
  593.         else:
  594.             system = 'Solaris'
  595.     elif system == 'IRIX64':
  596.         system = 'IRIX'
  597.         if version:
  598.             version = version + ' (64bit)'
  599.         else:
  600.             version = '64bit'
  601.     elif system in ('win32', 'win16'):
  602.         system = 'Windows'
  603.     
  604.     return (system, release, version)
  605.  
  606.  
  607. def _platform(*args):
  608.     ''' Helper to format the platform string in a filename
  609.         compatible format e.g. "system-version-machine".
  610.     '''
  611.     platform = string.join(map(string.strip, filter(len, args)), '-')
  612.     replace = string.replace
  613.     platform = replace(platform, ' ', '_')
  614.     platform = replace(platform, '/', '-')
  615.     platform = replace(platform, '\\', '-')
  616.     platform = replace(platform, ':', '-')
  617.     platform = replace(platform, ';', '-')
  618.     platform = replace(platform, '"', '-')
  619.     platform = replace(platform, '(', '-')
  620.     platform = replace(platform, ')', '-')
  621.     platform = replace(platform, 'unknown', '')
  622.     while None:
  623.         cleaned = replace(platform, '--', '-')
  624.         if cleaned == platform:
  625.             break
  626.         
  627.         platform = cleaned
  628.         continue
  629.         while platform[-1] == '-':
  630.             platform = platform[:-1]
  631.         return platform
  632.  
  633.  
  634. def _node(default = ''):
  635.     ''' Helper to determine the node name of this machine.
  636.     '''
  637.     
  638.     try:
  639.         import socket as socket
  640.     except ImportError:
  641.         return default
  642.  
  643.     
  644.     try:
  645.         return socket.gethostname()
  646.     except socket.error:
  647.         return default
  648.  
  649.  
  650. if not hasattr(os.path, 'abspath'):
  651.     
  652.     def _abspath(path, isabs = os.path.isabs, join = os.path.join, getcwd = os.getcwd, normpath = os.path.normpath):
  653.         if not isabs(path):
  654.             path = join(getcwd(), path)
  655.         
  656.         return normpath(path)
  657.  
  658. else:
  659.     _abspath = os.path.abspath
  660.  
  661. def _follow_symlinks(filepath):
  662.     ''' In case filepath is a symlink, follow it until a
  663.         real file is reached.
  664.     '''
  665.     filepath = _abspath(filepath)
  666.     while os.path.islink(filepath):
  667.         filepath = os.path.normpath(os.path.join(os.path.dirname(filepath), os.readlink(filepath)))
  668.     return filepath
  669.  
  670.  
  671. def _syscmd_uname(option, default = ''):
  672.     """ Interface to the system's uname command.
  673.     """
  674.     if sys.platform in ('dos', 'win32', 'win16', 'os2'):
  675.         return default
  676.     
  677.     
  678.     try:
  679.         f = os.popen('uname %s 2> /dev/null' % option)
  680.     except (AttributeError, os.error):
  681.         return default
  682.  
  683.     output = string.strip(f.read())
  684.     rc = f.close()
  685.     if not output or rc:
  686.         return default
  687.     else:
  688.         return output
  689.  
  690.  
  691. def _syscmd_file(target, default = ''):
  692.     """ Interface to the system's file command.
  693.  
  694.         The function uses the -b option of the file command to have it
  695.         ommit the filename in its output and if possible the -L option
  696.         to have the command follow symlinks. It returns default in
  697.         case the command should fail.
  698.  
  699.     """
  700.     target = _follow_symlinks(target)
  701.     
  702.     try:
  703.         f = os.popen('file %s 2> /dev/null' % target)
  704.     except (AttributeError, os.error):
  705.         return default
  706.  
  707.     output = string.strip(f.read())
  708.     rc = f.close()
  709.     if not output or rc:
  710.         return default
  711.     else:
  712.         return output
  713.  
  714. _default_architecture = {
  715.     'win32': ('', 'WindowsPE'),
  716.     'win16': ('', 'Windows'),
  717.     'dos': ('', 'MSDOS') }
  718. _architecture_split = re.compile('[\\s,]').split
  719.  
  720. def architecture(executable = sys.executable, bits = '', linkage = ''):
  721.     ''' Queries the given executable (defaults to the Python interpreter
  722.         binary) for various architecture information.
  723.  
  724.         Returns a tuple (bits,linkage) which contains information about
  725.         the bit architecture and the linkage format used for the
  726.         executable. Both values are returned as strings.
  727.  
  728.         Values that cannot be determined are returned as given by the
  729.         parameter presets. If bits is given as \'\', the sizeof(pointer)
  730.         (or sizeof(long) on Python version < 1.5.2) is used as
  731.         indicator for the supported pointer size.
  732.  
  733.         The function relies on the system\'s "file" command to do the
  734.         actual work. This is available on most if not all Unix
  735.         platforms. On some non-Unix platforms where the "file" command
  736.         does not exist and the executable is set to the Python interpreter
  737.         binary defaults from _default_architecture are used.
  738.  
  739.     '''
  740.     if not bits:
  741.         import struct as struct
  742.         
  743.         try:
  744.             size = struct.calcsize('P')
  745.         except struct.error:
  746.             size = struct.calcsize('l')
  747.  
  748.         bits = str(size * 8) + 'bit'
  749.     
  750.     output = _syscmd_file(executable, '')
  751.     if not output and executable == sys.executable:
  752.         if _default_architecture.has_key(sys.platform):
  753.             (b, l) = _default_architecture[sys.platform]
  754.             if b:
  755.                 bits = b
  756.             
  757.             if l:
  758.                 linkage = l
  759.             
  760.         
  761.         return (bits, linkage)
  762.     
  763.     fileout = _architecture_split(output)[1:]
  764.     if 'executable' not in fileout:
  765.         return (bits, linkage)
  766.     
  767.     if '32-bit' in fileout:
  768.         bits = '32bit'
  769.     elif 'N32' in fileout:
  770.         bits = 'n32bit'
  771.     elif '64-bit' in fileout:
  772.         bits = '64bit'
  773.     
  774.     if 'ELF' in fileout:
  775.         linkage = 'ELF'
  776.     elif 'PE' in fileout:
  777.         if 'Windows' in fileout:
  778.             linkage = 'WindowsPE'
  779.         else:
  780.             linkage = 'PE'
  781.     elif 'COFF' in fileout:
  782.         linkage = 'COFF'
  783.     elif 'MS-DOS' in fileout:
  784.         linkage = 'MSDOS'
  785.     
  786.     return (bits, linkage)
  787.  
  788. _uname_cache = None
  789.  
  790. def uname():
  791.     """ Fairly portable uname interface. Returns a tuple
  792.         of strings (system,node,release,version,machine,processor)
  793.         identifying the underlying platform.
  794.  
  795.         Note that unlike the os.uname function this also returns
  796.         possible processor information as an additional tuple entry.
  797.  
  798.         Entries which cannot be determined are set to ''.
  799.  
  800.     """
  801.     global _uname_cache
  802.     if _uname_cache is not None:
  803.         return _uname_cache
  804.     
  805.     
  806.     try:
  807.         (system, node, release, version, machine) = os.uname()
  808.     except AttributeError:
  809.         system = sys.platform
  810.         release = ''
  811.         version = ''
  812.         node = _node()
  813.         machine = ''
  814.         processor = ''
  815.         use_syscmd_ver = 1
  816.         if system == 'win32':
  817.             (release, version, csd, ptype) = win32_ver()
  818.             if release and version:
  819.                 use_syscmd_ver = 0
  820.             
  821.         
  822.         if use_syscmd_ver:
  823.             (system, release, version) = _syscmd_ver(system)
  824.             if system == 'Microsoft Windows':
  825.                 system = 'Windows'
  826.             
  827.         
  828.         if system in ('win32', 'win16'):
  829.             if not version:
  830.                 if system == 'win32':
  831.                     version = '32bit'
  832.                 else:
  833.                     version = '16bit'
  834.             
  835.             system = 'Windows'
  836.         elif system[:4] == 'java':
  837.             (release, vendor, vminfo, osinfo) = java_ver()
  838.             system = 'Java'
  839.             version = string.join(vminfo, ', ')
  840.             if not version:
  841.                 version = vendor
  842.             
  843.         elif os.name == 'mac':
  844.             (version, stage, nonrel) = (release,)
  845.             machine = mac_ver()
  846.             system = 'MacOS'
  847.         
  848.     except:
  849.         system in ('win32', 'win16')
  850.  
  851.     if system == 'OpenVMS':
  852.         if not release or release == '0':
  853.             release = version
  854.             version = ''
  855.         
  856.         
  857.         try:
  858.             import vms_lib as vms_lib
  859.         except ImportError:
  860.             pass
  861.  
  862.         (csid, cpu_number) = vms_lib.getsyi('SYI$_CPU', 0)
  863.         if cpu_number >= 128:
  864.             processor = 'Alpha'
  865.         else:
  866.             processor = 'VAX'
  867.     else:
  868.         processor = _syscmd_uname('-p', '')
  869.     if system == 'unknown':
  870.         system = ''
  871.     
  872.     if node == 'unknown':
  873.         node = ''
  874.     
  875.     if release == 'unknown':
  876.         release = ''
  877.     
  878.     if version == 'unknown':
  879.         version = ''
  880.     
  881.     if machine == 'unknown':
  882.         machine = ''
  883.     
  884.     if processor == 'unknown':
  885.         processor = ''
  886.     
  887.     if system == 'Microsoft' and release == 'Windows':
  888.         system = 'Windows'
  889.         release = 'Vista'
  890.     
  891.     _uname_cache = (system, node, release, version, machine, processor)
  892.     return _uname_cache
  893.  
  894.  
  895. def system():
  896.     """ Returns the system/OS name, e.g. 'Linux', 'Windows' or 'Java'.
  897.  
  898.         An empty string is returned if the value cannot be determined.
  899.  
  900.     """
  901.     return uname()[0]
  902.  
  903.  
  904. def node():
  905.     """ Returns the computer's network name (which may not be fully
  906.         qualified)
  907.  
  908.         An empty string is returned if the value cannot be determined.
  909.  
  910.     """
  911.     return uname()[1]
  912.  
  913.  
  914. def release():
  915.     """ Returns the system's release, e.g. '2.2.0' or 'NT'
  916.  
  917.         An empty string is returned if the value cannot be determined.
  918.  
  919.     """
  920.     return uname()[2]
  921.  
  922.  
  923. def version():
  924.     """ Returns the system's release version, e.g. '#3 on degas'
  925.  
  926.         An empty string is returned if the value cannot be determined.
  927.  
  928.     """
  929.     return uname()[3]
  930.  
  931.  
  932. def machine():
  933.     """ Returns the machine type, e.g. 'i386'
  934.  
  935.         An empty string is returned if the value cannot be determined.
  936.  
  937.     """
  938.     return uname()[4]
  939.  
  940.  
  941. def processor():
  942.     """ Returns the (true) processor name, e.g. 'amdk6'
  943.  
  944.         An empty string is returned if the value cannot be
  945.         determined. Note that many platforms do not provide this
  946.         information or simply return the same value as for machine(),
  947.         e.g.  NetBSD does this.
  948.  
  949.     """
  950.     return uname()[5]
  951.  
  952. _sys_version_parser = re.compile('([\\w.+]+)\\s*\\(#?([^,]+),\\s*([\\w ]+),\\s*([\\w :]+)\\)\\s*\\[([^\\]]+)\\]?')
  953. _sys_version_cache = None
  954.  
  955. def _sys_version():
  956.     """ Returns a parsed version of Python's sys.version as tuple
  957.         (version, buildno, builddate, compiler) referring to the Python
  958.         version, build number, build date/time as string and the compiler
  959.         identification string.
  960.  
  961.         Note that unlike the Python sys.version, the returned value
  962.         for the Python version will always include the patchlevel (it
  963.         defaults to '.0').
  964.  
  965.     """
  966.     global _sys_version_cache
  967.     if _sys_version_cache is not None:
  968.         return _sys_version_cache
  969.     
  970.     (version, buildno, builddate, buildtime, compiler) = _sys_version_parser.match(sys.version).groups()
  971.     builddate = builddate + ' ' + buildtime
  972.     l = string.split(version, '.')
  973.     if len(l) == 2:
  974.         l.append('0')
  975.         version = string.join(l, '.')
  976.     
  977.     _sys_version_cache = (version, buildno, builddate, compiler)
  978.     return _sys_version_cache
  979.  
  980.  
  981. def python_version():
  982.     """ Returns the Python version as string 'major.minor.patchlevel'
  983.  
  984.         Note that unlike the Python sys.version, the returned value
  985.         will always include the patchlevel (it defaults to 0).
  986.  
  987.     """
  988.     return _sys_version()[0]
  989.  
  990.  
  991. def python_version_tuple():
  992.     ''' Returns the Python version as tuple (major, minor, patchlevel)
  993.         of strings.
  994.  
  995.         Note that unlike the Python sys.version, the returned value
  996.         will always include the patchlevel (it defaults to 0).
  997.  
  998.     '''
  999.     return string.split(_sys_version()[0], '.')
  1000.  
  1001.  
  1002. def python_build():
  1003.     ''' Returns a tuple (buildno, builddate) stating the Python
  1004.         build number and date as strings.
  1005.  
  1006.     '''
  1007.     return _sys_version()[1:3]
  1008.  
  1009.  
  1010. def python_compiler():
  1011.     ''' Returns a string identifying the compiler used for compiling
  1012.         Python.
  1013.  
  1014.     '''
  1015.     return _sys_version()[3]
  1016.  
  1017. _platform_cache = { }
  1018.  
  1019. def platform(aliased = 0, terse = 0):
  1020.     ''' Returns a single string identifying the underlying platform
  1021.         with as much useful information as possible (but no more :).
  1022.  
  1023.         The output is intended to be human readable rather than
  1024.         machine parseable. It may look different on different
  1025.         platforms and this is intended.
  1026.  
  1027.         If "aliased" is true, the function will use aliases for
  1028.         various platforms that report system names which differ from
  1029.         their common names, e.g. SunOS will be reported as
  1030.         Solaris. The system_alias() function is used to implement
  1031.         this.
  1032.  
  1033.         Setting terse to true causes the function to return only the
  1034.         absolute minimum information needed to identify the platform.
  1035.  
  1036.     '''
  1037.     result = _platform_cache.get((aliased, terse), None)
  1038.     if result is not None:
  1039.         return result
  1040.     
  1041.     (system, node, release, version, machine, processor) = uname()
  1042.     if machine == processor:
  1043.         processor = ''
  1044.     
  1045.     if aliased:
  1046.         (system, release, version) = system_alias(system, release, version)
  1047.     
  1048.     if system == 'Windows':
  1049.         (rel, vers, csd, ptype) = win32_ver(version)
  1050.         if terse:
  1051.             platform = _platform(system, release)
  1052.         else:
  1053.             platform = _platform(system, release, version, csd)
  1054.     elif system in ('Linux',):
  1055.         (distname, distversion, distid) = dist('')
  1056.         if distname and not terse:
  1057.             platform = _platform(system, release, machine, processor, 'with', distname, distversion, distid)
  1058.         else:
  1059.             (libcname, libcversion) = libc_ver(sys.executable)
  1060.             platform = _platform(system, release, machine, processor, 'with', libcname + libcversion)
  1061.     elif system == 'Java':
  1062.         (os_name, os_version, os_arch) = (r, v, vminfo)
  1063.         if terse:
  1064.             platform = _platform(system, release, version)
  1065.         else:
  1066.             platform = _platform(system, release, version, 'on', os_name, os_version, os_arch)
  1067.     elif system == 'MacOS':
  1068.         if terse:
  1069.             platform = _platform(system, release)
  1070.         else:
  1071.             platform = _platform(system, release, machine)
  1072.     elif terse:
  1073.         platform = _platform(system, release)
  1074.     else:
  1075.         (bits, linkage) = architecture(sys.executable)
  1076.         platform = _platform(system, release, machine, processor, bits, linkage)
  1077.     _platform_cache[(aliased, terse)] = platform
  1078.     return platform
  1079.  
  1080. if __name__ == '__main__':
  1081.     if not 'terse' in sys.argv:
  1082.         pass
  1083.     terse = '--terse' in sys.argv
  1084.     if 'nonaliased' not in sys.argv:
  1085.         pass
  1086.     aliased = '--nonaliased' not in sys.argv
  1087.     print platform(aliased, terse)
  1088.     sys.exit(0)
  1089.  
  1090.